feat(tee): share the SNP report union and check the declared signature algorithm - #260
Merged
Conversation
…e algorithm Phase A2 of consolidating the TEE verification stack. cmcp and ca2a carried four copies of the SEV-SNP report layout between them, two of them inside cmcp alone. All four agree on every offset, so this is a union rather than a reconciliation, but four copies is four chances to drift. SnpReport gains guest_svn, vmpl and signature_algo, which the downstream copies parsed and this one did not. load_snp_cert_chain() becomes public; it splits a concatenated PEM into (vcek, ask, ark) by shape rather than order and came from cmcp, which had it and this package did not. verify_snp_signature() now checks the report's declared sig_algo before verifying. It assumed ECDSA-P384/SHA-384 because that is the only scheme AMD has defined, and verified under it without confirming the report agreed. Both downstream copies enforced this, so consolidating onto the shared one would have silently dropped a check that already existed. Enforcing it surfaced two synthetic fixtures here that left sig_algo at zero, which no AMD processor emits: the genuine capture in vectors/snp carries 1. Both described a report that cannot exist. Corrected rather than worked around, the same shape of defect as the cmcp TPM fixture found in 0.8.0. 648 passed, 16 skipped. Refs #204 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 2, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase A2 of consolidating the TEE verification stack, following #258 (TPM).
The scale of the duplication
Four copies of the SEV-SNP report layout across the org, two of them inside cmcp alone (
cmcp_verify/sev_snp.pyandcmcp_runtime/tee/sev_snp.py, byte-identical ctypes structs), plusca2a_runtime/tee/sev_snp.pyand this one. Every offset agrees in all four, so this is a union rather than a reconciliation. Four copies is still four chances to drift, and the TDX type-6 header fix is what drift looks like when it happens.Union additions
SnpReportgainsguest_svn,vmplandsignature_algo. The downstream copies parsed these and this one did not, so a consumer of agent-manifest could not enforce checks those copies enforced.load_snp_cert_chain()becomes public. It splits a concatenated PEM into(vcek, ask, ark)by shape rather than order — the VCEK is the only EC leaf, and of the two RSA certificates the self-signed one is the ARK. It came from cmcp.The check that was missing here
verify_snp_signature()assumed ECDSA-P384/SHA-384, because that is the only scheme AMD has defined, and verified under it without confirming the report said so. Both downstream copies checkedsig_algofirst. Consolidating onto the shared implementation as it stood would have silently dropped a check that already existed in the code being deleted.That is the specific hazard of this whole exercise, and the second time it has shown up: in 0.8.0 the shared TPM parser was narrower than cmcp's. Port-then-delete keeps catching it, and it is why every remaining phase gets a behavioural diff before the delete lands.
What enforcing it found
Two synthetic fixtures in this repo left
sig_algoat zero, which no AMD processor emits — the genuine capture intests/vectors/snp/azure_snp_report_redacted.bincarries 1. Both described a report that cannot exist. Corrected rather than worked around, the same shape of defect as the cmcp TPM fixture in 0.8.0.New coverage includes the realistic failure recorded in cmcp's hardware-validation log: passing AMD KDS's
cert_chainendpoint output whole, which is ASK + ARK with no VCEK, now fails loudly instead of proceeding with two of the three.Testing
648 passed, 16 skipped.Next
0.9.0, then cmcp and ca2a delete their copies. The provider/collector layer that wraps these structs is A5 and is not touched here.
🤖 Generated with Claude Code